﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace EasyCommonCore.Common
{
    /// <summary>
    /// 类型转换
    /// </summary>
    public static class TypeConversionCommon
    {
        #region Methods

        #region 转换为String类型

        /// <summary>
        /// 转换为String类型,将输入的字符串转换为string类型
        /// 转换失败为-1
        /// </summary>
        /// <param name="parameter">参数--字符串</param>
        /// <param name="number">保留几位小数（默认保留2位）,>=0</param>
        /// <param name="isNeedZeron">是否需要小数点后的0</param>
        /// <param name="defaultErrParameter">转换出错默认值</param>
        /// <returns></returns>
        public static string ConvertDecimalToString(this object parameter, int number = 2, bool isNeedZeron = false, string defaultErrParameter = "")
        {
            string result;
            if (parameter == null)
                return defaultErrParameter;
            var parameterTemp = parameter.ToString();
            if (!String.IsNullOrEmpty(parameterTemp))
            {
                try
                {
                    result = Decimal.Parse(parameterTemp).ToString("f" + number);
                    if (!isNeedZeron)
                    {
                        //如果不需要尾部的.00
                        if (!result.Contains("."))
                        {
                            return result;
                        }
                        int i = 0;
                        for (int j = result.Split('.')[1].Length; j > 0; j--)
                        {
                            if (result.Split('.')[1].Substring(j - 1, 1) == "0")
                            {
                                i++; //需要删除后多少位
                            }
                        }
                        result = result.Substring(0, result.Length - i);
                        return result;
                    }
                }
                catch (Exception)
                {
                    return defaultErrParameter;
                }
            }
            else
            {
                result = isNeedZeron ? (0).ToString("f" + number) : "0";
            }
            return result;
        }
        #endregion

        #region 时间类型转换为字符串类型

        /// <summary>
        /// 时间类型转换为字符串类型
        /// </summary>
        /// <param name="parameter">需要转换的时间类型</param>
        /// <param name="format">格式化 默认转换参数 yyyy-MM-dd HH:mm</param>
        /// <param name="defaultErrParameter">默认转换失败为""</param>
        /// <returns></returns>
        public static string ConvertDateTimeToString(this DateTime? parameter, string format = "yyyy-MM-dd HH:mm", string defaultErrParameter = "")
        {
            if (parameter == null)
            {
                return defaultErrParameter;
            }
            else
            {
                return ((DateTime)parameter).ConvertDateTimeToString(format);
            }
        }

        /// <summary>
        /// 时间类型转换为字符串类型
        /// </summary>
        /// <param name="parameter">需要转换的时间类型</param>
        /// <param name="format">格式化 默认转换参数 yyyy-MM-dd HH:mm</param>
        /// <param name="defaultErrParameter">默认转换失败为""</param>
        /// <returns></returns>
        public static string ConvertDateTimeToString(this DateTime parameter, string format = "yyyy-MM-dd HH:mm", string defaultErrParameter = "")
        {
            string result;
            try
            {
                result = parameter.ToString(format);
            }
            catch
            {
                result = defaultErrParameter;
            }
            return result;
        }

        #endregion

        #region 转换为int类型

        /// <summary>
        /// 转换为int类型
        /// 转换失败默认为-1
        /// </summary>
        /// <param name="parameter">参数--字符串</param>
        /// <param name="defaultErrParameter">转换失败返回的值，默认-1</param>
        /// <returns></returns>
        public static int ConvertToInt(this object parameter, int defaultErrParameter = -1)
        {
            int result = defaultErrParameter;
            if (parameter != null)
            {
                try
                {
                    result = Int32.Parse(parameter.ToString());
                }
                catch
                {
                    result = defaultErrParameter;
                }
            }
            return result;
        }
        #endregion

        #region 转换为short类型

        /// <summary>
        /// 转换为short类型
        /// 转换失败为-1
        /// </summary>
        /// <param name="parameter">参数--字符串</param>
        /// <param name="defaultErrParameter">默认转换失败参数-1，可以自定义</param>
        /// <returns></returns>
        public static short ConvertToShort(this object parameter, short defaultErrParameter = -1)
        {
            short result = defaultErrParameter;
            if (parameter != null)
            {
                try
                {
                    result = Int16.Parse(parameter.ToString());
                }
                catch
                {
                    result = defaultErrParameter;
                }
            }
            return result;
        }
        #endregion

        #region 转换为string类型
        /// <summary>
        /// 转换为string类型
        /// 转换失败为""
        /// </summary>
        /// <param name="parameter">参数--字符串</param>
        /// <returns></returns>
        public static string ConvertToString(this object parameter)
        {
            string result = "";
            if (parameter != null)
            {
                return parameter.ToString();
            }
            return result;
        }
        #endregion

        #region 转换为时间类型

        /// <summary>
        /// 转换为时间类型
        /// 转换失败为Null
        /// </summary>
        /// <param name="parameter">参数--字符串</param>
        /// <param name="defaultErrParamter">默认转换失败返回null</param>
        /// <returns></returns>
        public static DateTime? ConvertToDateTime(this object parameter, DateTime? defaultErrParamter = null)
        {
            try
            {
                if (!String.IsNullOrEmpty(parameter?.ToString()))
                    return (DateTime?)parameter;
                else
                    return defaultErrParamter;
            }
            catch (Exception)
            {
                return defaultErrParamter;
            }
        }
        #endregion

        #region 转换为Bool类型

        /// <summary>
        /// 转换为Bool类型
        /// 转换失败为Null
        /// </summary>
        /// <param name="parameter">参数--字符串</param>
        /// <param name="defaultErrParamter">默认转换失败</param>
        /// <returns></returns>
        public static bool? ConvertToBool(this object parameter, bool? defaultErrParamter = null)
        {
            try
            {
                return (bool?)parameter;
            }
            catch (Exception)
            {
                return defaultErrParamter;
            }
        }

        #endregion

        #region 清空小数点后0
        /// <summary>
        /// 清楚小数点后的0
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string ClearDecimal(this string str)
        {
            if (String.IsNullOrEmpty(str))
                return "0";
            str = Single.Parse(str).ToString("0.00");
            if (Int32.Parse(str.Substring(str.IndexOf(".", StringComparison.Ordinal) + 1)) == 0)
            {
                return str.Substring(0, str.IndexOf(".", StringComparison.Ordinal));
            }
            return str;
        }

        #endregion

        #region 转换为Decimal类型

        /// <summary>
        /// 转换为Decimal类型
        /// 转换失败为-1
        /// </summary>
        /// <param name="parameter">参数--字符串</param>
        /// <param name="defaultErrParameter">默认转换失败参数</param>
        /// <returns></returns>
        public static Decimal ConvertToDecimal(this object parameter, decimal defaultErrParameter = -1)
        {
            Decimal result = -1;
            if (parameter != null)
            {
                try
                {
                    result = Decimal.Parse((string)parameter);
                }
                catch
                {
                    result = -1;
                }
            }
            return result;
        }
        #endregion

        #region 转换为时间类型

        /// <summary>
        /// 转换为时间类型
        /// </summary>
        /// <param name="dateParameter">需要转换的时间</param>
        /// <param name="reg">转换的时间类型</param>
        /// <param name="defaultErrParameter">默认转换失败返回</param>
        /// <returns></returns>
        public static string ConvertToDate(this string dateParameter, string reg, string defaultErrParameter = "")
        {
            if (!String.IsNullOrEmpty(dateParameter))
            {
                return DateTime.Parse(dateParameter).ToString(reg);
            }
            else
            {
                return defaultErrParameter;
            }
        }

        /// <summary>
        /// 转换为时间
        /// </summary>
        /// <param name="dateParameter">需要转换的时间</param>
        /// <param name="defaultErrParameter">默认转换失败返回</param>
        /// <returns></returns>
        public static DateTime? ConvertToDate(this string dateParameter, DateTime? defaultErrParameter = null)
        {
            try
            {
                if (!String.IsNullOrEmpty(dateParameter))
                {
                    return DateTime.Parse(dateParameter);
                }
            }
            catch (Exception)
            {
                // ignored
            }
            return defaultErrParameter;
        }
        #endregion

        #region Base64编码
        /// <summary>
        /// Base64编码
        /// </summary>
        /// <param name="code">需要编码的字符串</param>
        /// <returns></returns>
        public static string EncodeBase64(this string code)
        {
            return Convert.ToBase64String(Encoding.UTF8.GetBytes(code));
        }
        #endregion

        #region  Base64解码
        /// <summary>
        /// Base64解码
        /// </summary>
        /// <param name="code">需要解码的字符串</param>
        /// <returns></returns>
        public static string DecodeBase64(this string code)
        {
            try
            {
                return Encoding.UTF8.GetString(Convert.FromBase64String(code));
            }
            catch (Exception exp)
            {
                return exp.Message;
            }
        }
        #endregion

        #region 加密显示以*表示
        /// <summary>
        /// 加密显示以*表示
        /// </summary>
        /// <param name="number">显示N位*,-1默认显示6位</param>
        /// <returns></returns>
        public static string GetContentByEncryption(int number)
        {
            int encryptionLength = 6;//默认加密后数据显示6位***
            string result = "";//结果
            if (number == -1 || number < 0)
            {
                encryptionLength = 6;
            }
            for (int i = 0; i < encryptionLength; i++)
            {
                result += "*";
            }
            return result;
        }
        #endregion

        #region 将list集合转换为字符串
        /// <summary>
        /// 将list集合转换为字符串，中间以,分割
        /// </summary>
        /// <param name="parameterList"></param>
        /// <returns></returns>
        public static string ConvertListToString(List<int?> parameterList)
        {
            string result = parameterList.Aggregate("", (current, i) => current + (i.ToString() + ","));
            if (!String.IsNullOrWhiteSpace(result))
            {
                result = result.Substring(0, result.Length - 1);
            }
            return result;
        }

        public static string ConvertListToString(List<string> parameterList)
        {
            string result = parameterList.Aggregate("", (current, i) => current + (i.ToString() + ","));
            if (!String.IsNullOrWhiteSpace(result))
            {
                result = result.Substring(0, result.Length - 1);
            }
            return result;
        }
        #endregion

        #region 值互换(左边最小值,右边最大值)
        /// <summary>
        /// 值互换(左边最小值,右边最大值)
        /// </summary>
        /// <param name="minParameter">最小值</param>
        /// <param name="maxParameter">最大值</param>
        public static void ChangeResult(ref int? minParameter, ref int? maxParameter)
        {
            if (minParameter > maxParameter)
            {
                var temp = maxParameter;
                maxParameter = minParameter;
                minParameter = temp;
            }
        }

        /// <summary>
        /// 值互换(左边最小值,右边最大值)
        /// </summary>
        /// <param name="minParameter">最小值</param>
        /// <param name="maxParameter">最大值</param>
        public static void ChangeResult(ref decimal? minParameter, ref decimal? maxParameter)
        {
            if (minParameter > maxParameter)
            {
                var temp = maxParameter;
                maxParameter = minParameter;
                minParameter = temp;
            }
        }

        /// <summary>
        /// 值互换(左边最小值,右边最大值)
        /// </summary>
        /// <param name="minParameter">最小值</param>
        /// <param name="maxParameter">最大值</param>
        public static void ChangeResult(ref DateTime? minParameter, ref DateTime? maxParameter)
        {
            if (minParameter > maxParameter)
            {
                var temp = maxParameter;
                maxParameter = minParameter;
                minParameter = temp;
            }
        }
        #endregion

        #region 字符串转换为泛型集合
        /// <summary>
        /// 字符串转化为泛型集合
        /// </summary>
        /// <param name="str">字符串</param>
        /// <param name="splitstr">要分割的字符,默认以,分割</param>
        /// <returns></returns>
        public static List<T> ConvertStrToList<T>(this string str, char splitstr = ',')
        {
            if (String.IsNullOrEmpty(str))
            {
                return new List<T>();
            }
            string[] strarray = str.Split(splitstr);
            return (from s in strarray where s != "" select (T)Convert.ChangeType(s, typeof(T))).ToList();
        }
        #endregion

        #region 合并两个类型一致的泛型集合
        /// <summary>
        /// 合并两个类型一致的泛型
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="a">泛型A</param>
        /// <param name="b">泛型B</param>
        /// <returns></returns>
        public static List<T> ConvertTJoinOtherT<T>(this List<T> a, List<T> b)
        {
            if (a == null)
            {
                a = new List<T>();
            }
            if (b == null)
            {
                b = new List<T>();
            }
            List<T> c = a.ToList();
            c.AddRange(b);
            return c;
        }

        #endregion

        #region 在尾部追加,或者其他字符
        /// <summary>
        /// 在尾部追加,或者其他字符,默认追加,
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="a">需要转换的T类型的list集合</param>
        /// <param name="splitstr">追加的字符，默认为,</param>
        /// <returns></returns>
        public static string ConvertListToString<T>(this List<T> a, char splitstr = ',')
        {
            if (a == null)
            {
                a = new List<T>();
            }
            var result = a.Where(item => item != null && !String.IsNullOrWhiteSpace(item.ToString())).Aggregate("", (current, item) => current + (item.ToString() + splitstr));
            if (result.Length > 0 && result.Substring(result.Length - 1, 1) == splitstr.ToString())
                return result.Substring(0, result.Length - 1);
            return result;
        }

        #endregion

        #region 在尾部追加,或者追加其它字符，默认追加,
        /// <summary>
        /// 在尾部追加,或者追加其它字符，默认追加,
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="a">需要转换的T类型的list集合</param>
        /// <param name="splitstr">在T类型两边添加的字符串，例如：'张三','李四'</param>
        /// <param name="splitstr2">追加的字符，默认为,</param>
        /// <returns></returns>
        public static string ConvertListToString<T>(this List<T> a, string splitstr = "'", char splitstr2 = ',')
        {
            if (a == null)
            {
                a = new List<T>();
            }
            var result = a.Where(item => item != null).Aggregate("", (current, item) => current + splitstr + item + splitstr + splitstr2);
            if (result.Length > 0 && result.Substring(result.Length - 1, 1) == splitstr)
                return result.Substring(0, result.Length - 1);
            return result;
        }

        #endregion

        #region 得到新增的集合以及被删除的集合
        /// <summary>
        /// 得到新增的集合以及被删除的集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="oldObject">老的集合</param>
        /// <param name="newOject">新的集合</param>
        /// <param name="newAddObject">新增加的集合</param>
        /// <param name="deleteObject">被删除的集合</param>
        /// <param name="alwaysExist">总是存在的集合</param>
        public static void ConvertToCheckData<T>(List<T> oldObject, List<T> newOject, out List<T> newAddObject,
            out List<T> deleteObject, out List<T> alwaysExist)
        {
            newAddObject = new List<T>();
            deleteObject = new List<T>();
            alwaysExist = new List<T>();
            if (oldObject == null)
            {
                oldObject = new List<T>();
            }
            if (newOject == null)
            {
                newOject = new List<T>();
            }
            foreach (var objects in oldObject)
            {
                if (newOject.Contains(objects))
                {
                    newAddObject.Remove(objects);//从新的中删除原来已存在的
                    alwaysExist.Add(objects);//始终存在的
                }
                else
                {
                    deleteObject.Add(objects);//被删除的
                }
            }
        }

        #endregion

        #region 转为字节数组
        /// <summary>
        /// 转为字节数组
        /// </summary>
        /// <param name="stream">流</param>
        /// <returns></returns>
        public static byte[] ConvertStreamToByte(this Stream stream)
        {
            byte[] bytes = new byte[stream.Length];
            stream.Read(bytes, 0, bytes.Length);
            // 设置当前流的位置为流的开始
            stream.Seek(0, SeekOrigin.Begin);
            return bytes;
        }

        #endregion

        #region 大小写转换

        #region 转为大写

        /// <summary>
        /// 转为大写
        /// </summary>
        /// <param name="parameter">需要转换的参数</param>
        /// <returns></returns>
        public static string ToUppers(this string parameter)
        {
            if (String.IsNullOrEmpty(parameter))
            {
                return "";
            }
            return parameter.ToUpper();
        }

        #endregion

        #region 转为小写

        /// <summary>
        /// 转为小写
        /// </summary>
        /// <param name="parameter">需要转换的参数</param>
        /// <returns></returns>
        public static string ToLowers(this string parameter)
        {
            if (String.IsNullOrEmpty(parameter))
            {
                return "";
            }
            return parameter.ToLower();
        }

        #endregion

        #endregion

        #region 求余数
        /// <summary>
        /// 根据parameter1与parameter2求余数
        /// </summary>
        /// <param name="parameter1"></param>
        /// <param name="parameter2"></param>
        /// <param name="parameter3"></param>
        public static void DivRem(Int32 parameter1, Int32 parameter2, out Int32 parameter3)
        {
            parameter3 = parameter1 / parameter2;
        }

        /// <summary>
        /// 根据parameter1与parameter2求余数
        /// </summary>
        /// <param name="parameter1"></param>
        /// <param name="parameter2"></param>
        /// <param name="parameter3"></param>
        public static void DivRem(Int64 parameter1, Int64 parameter2,out Int64 parameter3)
        {
            parameter3 = parameter1 / parameter2;
        }
        #endregion

        #region 字符串转Stream
        /// <summary>
        /// 字符串转Stream
        /// </summary>
        /// <param name="parameter">待转换的字符串</param>
        /// <returns></returns>
        public static Stream ConvertStringToStream(this string parameter)
        {
            return new MemoryStream(Encoding.ASCII.GetBytes(parameter));
        }
        #endregion

        #endregion
    }
}
